<?php


namespace services\base;

use common\helpers\CommonHelper;
use common\helpers\RedisHelper;
use common\models\base\ToolCategory;
use common\components\Service;
use services\log\LogMemberOpService;
use Yii;

class ToolCategoryService extends Service
{
    /**
     * 通用选项列表
     * @param int $page
     * @param int $pageSize
     * @return array
     */
    public function toolCategoryList(int $page, int $pageSize): array
    {
        $query = ToolCategory::find()
            ->select(['id', 'pid', 'name', 'sort', 'is_builtin', 'status'])
            ->where([
                'status' => [ToolCategory::STATUS_ENABLE, ToolCategory::STATUS_INVALID],
                'pid' => 0
            ]);
        $list = $this->getListPageRes($query, $page, $pageSize, ['is_builtin' => SORT_DESC, 'status' => SORT_DESC, 'sort' => SORT_ASC, 'id' => SORT_DESC]);

        // 获取不是一级的分类
        $childCategory = ToolCategory::find()
            ->select(['id', 'pid', 'name', 'sort', 'is_builtin', 'status'])
            ->where(['status' => [ToolCategory::STATUS_INVALID, ToolCategory::STATUS_ENABLE]])
            ->andWhere(['>', 'pid', 0])
            ->orderBy(['status' => SORT_DESC, 'sort' => SORT_ASC, 'id' => SORT_DESC])
            ->asArray()
            ->all();

        // 整合数据
        $childList = [];
        foreach ($childCategory as $cs) {
            $cs['status_name'] = ToolCategory::$statuss[$cs['status']];
            $childList[$cs['pid']][] = $cs;
        }

        foreach ($list['list'] as &$val) {
            $val['status_name'] = ToolCategory::$statuss[$val['status']];
            $val['children'] = [];
            if (isset($childList[$val['id']])) {
                $val['children'] = $childList[$val['id']];
            }
        }
        return $list;
    }

    /**
     * 素材分类详情
     * @param int $id
     * @return array
     */
    public function getInfo(int $id): array
    {
        $list = [];
        $pid = 0;
        $info = ToolCategory::findOne($id);
        if ($info) {
            $list['list'] = $info;
            $pid = $info->pid;
        }
        $list['condition'] = self::getEditCondition($pid, 0);
        return $list;
    }

    /**
     * 获取正常
     * @param array|int|null $orIds 绑定IDs【正常+禁用】
     * @return ToolCategory[]
     */
    public static function getEnableListByIds($orIds = null, $pid = null, array $params = []): array
    {
        $query = ToolCategory::find()
            ->select(['*'])
            ->where([
                'status' => ToolCategory::STATUS_ENABLE,
            ]);
        if (!is_null($pid)) {// 编辑查找一级
            $query->andWhere(['pid' => $pid]);
        }
        if (isset($params['not_pid']) && $params['not_pid']) {
            $query->andWhere(['!=', 'id', $params['not_pid']]);
            $query->andWhere(['!=', 'pid', $params['not_pid']]);
        }
        if (!is_null($orIds)) {// 编辑查找已绑定选项
            $query->orWhere([
                'id' => $orIds,
                'status' => [ToolCategory::STATUS_INVALID, ToolCategory::STATUS_ENABLE],
            ]);
        }
        return $query->orderBy(['sort' => SORT_ASC, 'id' => SORT_ASC])->all();
    }

    /**
     * @param array|null $ids
     * @return ToolCategory[]
     */
    public static function getNormalListByIds(?array $ids = null): array
    {
        $query = ToolCategory::find()
            ->select(['*'])
            ->where([
                'status' => [ToolCategory::STATUS_INVALID, ToolCategory::STATUS_ENABLE],
            ]);
        if (!is_null($ids)) {
            $query->andWhere(['id' => $ids]);
        }
        return $query->orderBy(['is_builtin' => SORT_DESC, 'sort' => SORT_ASC, 'id' => SORT_DESC])->all();
    }

    /**
     * 获取列表筛选项
     * @return array
     */
    public static function getListCondition(): array
    {
        return CommonHelper::getListCondition(self::getNormalListByIds(), ['value_column' => 'id', 'label_column' => 'name', 'other_column' => ['pid']]);
    }

    /**
     * 获取编辑筛选项
     * @param int|array|null $orIds
     * @param null $pid
     * @return array
     */
    public static function getEditCondition($orIds = null, $pid = null, array $params = []): array
    {
        return CommonHelper::getListCondition(self::getEnableListByIds($orIds, $pid, $params), ['value_column' => 'id', 'label_column' => 'name', 'other_column' => ['pid']]);
    }

    /**
     * 获取年龄编辑筛选项
     * @param int|array|null $orIds
     * @return array
     */
    /*public static function getEditAgeCondition($orIds = null): array
    {
        if (is_null($orIds)) {
            $orIds = ToolCategory::find()->select(['id'])->where(['pid' => ToolCategory::ID_AGE])->column();
        }
        return CommonHelper::getListCondition(self::getEnableListByIds($orIds), ['value_column' => 'id', 'label_column' => 'name', 'other_column' => ['pid']]);
    }*/

    /**
     * 素材分类新增/编辑
     * @throws \Exception
     */
    public function updateToolCategory(array $params)
    {
        if (!isset($params['name']) || !$params['name']) {
            return CommonHelper::api(422, '名称必填');
        }
        $model = new ToolCategory();
        $scenario = 'create';
        $oldCommon = null;
        // 是否为编辑，编辑判断排除当前ID
        $whereId = [];
        if ($params['id']) {
            $model = ToolCategory::findOne($params['id']);
            if ($model->is_builtin == ToolCategory::IS_BUILTIN_YES) {
                return CommonHelper::api(422, '内置素材分类，不可编辑');
            }
            // 如果原来是一级，要改为二级则判断是否有子级，没有则能改为二级
            if ($params['pid'] > 0 && ToolCategory::findOne(['pid' => $params['id'], 'status' => [ToolCategory::STATUS_ENABLE, ToolCategory::STATUS_INVALID]])) {
                return CommonHelper::api(422, '存在子级分类，不能改为二级');
            }
            $whereId = ['!=', 'id', $params['id']];
            $oldCommon = self::getData($params['id']);
            $scenario = 'edit';
        }
        // 判断名称是否存在
        $check = ToolCategory::find()
            ->select(['id'])
            ->where([
                'name' => $params['name'],
                'pid' => $params['pid'],
                'status' => [ToolCategory::STATUS_ENABLE, ToolCategory::STATUS_INVALID]
            ])
            ->andWhere($whereId)
            ->one();
        if ($check) {
            return CommonHelper::api(422, '该分类已存在');
        }

        // 如果是一级停用，则所有子级状态改为停用
        if ($model->pid == 0 && $model->status == ToolCategory::STATUS_ENABLE && $params['status'] == ToolCategory::STATUS_INVALID) {
            // 更新子级状态为0
            ToolCategory::updateAll([
                'status' => ToolCategory::STATUS_INVALID,
                'operation_id' => Yii::$app->user->identity->member_id,
                'updated_at' => time()
            ], ['pid' => $params['id'], 'status' => ToolCategory::STATUS_ENABLE]);
        }
        // 如果是二级启用，则父级状态改为启用
        if ($model->pid != 0 && $model->status == ToolCategory::STATUS_INVALID && $params['status'] == ToolCategory::STATUS_ENABLE) {
            // 更新父级状态为1
            ToolCategory::updateAll([
                'status' => ToolCategory::STATUS_ENABLE,
                'operation_id' => Yii::$app->user->identity->member_id,
                'updated_at' => time()
            ], ['id' => $params['pid']]);
        }

        $model->pid = $params['pid'];
        $model->name = $params['name'];
        $model->status = $params['status'];
        $model->sort = $params['sort'] ?? 100;
        $model->operation_id = Yii::$app->user->identity->member_id;
        $model->saveAndCheckResult();

        // 添加日志
        LogMemberOpService::createToolCategoryLog($scenario, $model, $oldCommon);
        // 更新缓存
        RedisHelper::setToolCategory($model);
        return $model->id;
    }

    /**
     * 素材分类数据
     * @param int $id
     * @return ToolCategory|null
     */
    public static function getData(int $id): ?ToolCategory
    {
        return ToolCategory::findOne($id);
    }

    /**
     * 素材分类软删除
     * @throws \Exception
     */
    public function deleteToolCategory(array $params): array
    {
        $model = ToolCategory::findOne($params['id']);
        if ($model->is_builtin == ToolCategory::IS_BUILTIN_YES) {
            return CommonHelper::api(422, '内置素材分类，不可删除');
        }
        if ($model->status == ToolCategory::STATUS_DELETE) {
            return CommonHelper::api(422, '当前素材分类已删除');
        }
        if ($model->status != ToolCategory::STATUS_INVALID) {
            return CommonHelper::api(422, '素材分类不是停用状态不可删除');
        }

        if ($model->pid == 0) {
            // 更新子级状态为-1
            ToolCategory::updateAll([
                'status' => ToolCategory::STATUS_DELETE,
                'operation_id' => Yii::$app->user->identity->member_id,
                'updated_at' => time()
            ], ['pid' => $params['id']]);
        }
        // 更新状态为-1
        ToolCategory::updateAll([
            'status' => ToolCategory::STATUS_DELETE,
            'operation_id' => Yii::$app->user->identity->member_id,
            'updated_at' => time()
        ], ['id' => $params['id']]);

        // 添加日志
        LogMemberOpService::createToolCategoryLog('delete', self::getData($params['id']));
        // 删除缓存
        RedisHelper::delToolCategory($params['id']);
        return ['id' => $params['id']];
    }

    /**
     * 获取树状筛选条件
     * @return array
     */
    public static function getListTree(): array
    {
        return self::getTreeFormat(self::getListCondition());
    }

    /**
     * 获取编辑树状筛选条件
     * @return array
     */
    public static function getEditTree($orIds = null): array
    {
        return self::getTreeFormat(self::getEditCondition($orIds, null, ['not_pid' => ToolCategory::ID_AGE]));
    }

    /**
     * 格式化树数据
     * @param array $list
     * @param int $pid
     * @return array
     */
    public static function getTreeFormat(array $list, int $pid = 0): array
    {
        $data = [];
        foreach ($list as $row) {
            if ($row['pid'] != $pid) {
                continue;
            }
            $row['children'] = self::getTreeFormat($list, $row['value']);
            // 是否为年龄选项
            $row['is_age'] = $row['value'] == ToolCategory::ID_AGE || $row['pid'] == ToolCategory::ID_AGE ? 1 : 0;
            $data[] = $row;
        }
        return $data;
    }
}
